<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.5.3" />
<title>Clipf2db Developers Guide</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #dddddd;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}


@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

pre.verseblock-content {
  font-family: inherit;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(5);}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body>
<div id="header">
<h1>Clipf2db Developers Guide</h1>
<span id="author">Andy Nagels</span><br />
<span id="email"><tt>&lt;<a href="mailto:test@test.tst">test@test.tst</a>&gt;</tt></span><br />
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Clipf2db is a python cli application that parses a clipf txt output and puts it in a PostGresQL database.</p></div>
</div>
</div>
<h2 id="_introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="sidebarblock">
<div class="sidebar-content">
<div class="paragraph"><p>I suggest we skip the small talk and go directly to the <a href="#X2">the code explanation</a> and take a look at the inner workings.</p></div>
</div></div>
<div class="paragraph"><p>So nothing to see here</p></div>
<div class="sidebarblock">
<div class="sidebar-content">
<div class="sidebar-title">I said to skip this, didn&#8217;t I?</div>
<div class="paragraph"><p>Then skip it already&#8230;</p></div>
</div></div>
</div>
<h2 id="X1">2. Getting Started</h2>
<div class="sectionbody">
<h3 id="_getting_the_sources">2.1. Getting The Sources</h3><div style="clear:left"></div>
<div class="paragraph"><p>The source is hosted at googlecode(1) and can be found at <a href="http://code.google.com/p/clipf2db/source/checkout">http://code.google.com/p/clipf2db/source/checkout</a>.</p></div>
<h3 id="_installing_clipf2db">2.2. Installing Clipf2db</h3><div style="clear:left"></div>
<div class="paragraph"><p>Just checkout the code. You&#8217;re a programmer, so I know you understand it&#8230; ;)</p></div>
</div>
<h2 id="X2">3. clipf2db (withouth arguments)</h2>
<div class="sectionbody">
<h3 id="_general">3.1. General</h3><div style="clear:left"></div>
<div class="paragraph"><p>In this section, I will explain how the code works. Every section will contain a detailed explanation of 1 specific subset of the functionality of the application.</p></div>
<div class="paragraph"><p>This will print a usage message.</p></div>
<h3 id="_code">3.2. Code</h3><div style="clear:left"></div>
<div class="paragraph"><p>It&#8217;s not worth mentioning. Just a call of fUsage(), what more do you need to know?</p></div>
</div>
<h2 id="X3">4. Run with: clipf2db -h</h2>
<div class="sectionbody">
<h3 id="_general_2">4.1. General</h3><div style="clear:left"></div>
<div class="paragraph"><p>Yes, this also prints a usage message. The same one, in fact.</p></div>
<h3 id="_code_2">4.2. Code</h3><div style="clear:left"></div>
<div class="paragraph"><p>Also not worth mentioning, it&#8217;s the same call to fUsage().</p></div>
</div>
<h2 id="X4">5. Run with: clipf2db -f /path/to/clipf-operations-file</h2>
<div class="sectionbody">
<h3 id="_general_3">5.1. General</h3><div style="clear:left"></div>
<div class="dlist"><div class="title">Example file paths</div><dl>
<dt class="hdlist1">
<tt>~/.config/clipf/db/op</tt>
</dt>
<dd>
<p>
  This is the default path, where clipf2db looks.
</p>
</dd>
<dt class="hdlist1">
some/other/file
</dt>
<dd>
<p>
  Yeah, you can use any file.
</p>
</dd>
</dl></div>
<h3 id="_code_3">5.2. Code</h3><div style="clear:left"></div>
<div class="paragraph"><p>After executing clipf2db with the <em>-f</em> option, the code will first initialise the correct values and load the settings from the configuration file.</p></div>
<div class="listingblock">
<div class="title"><tt>__init__(self):</tt></div>
<div class="content">
<pre><tt>initialise exitstate 0, config filename and input file
load config
    config:
    get dbname, dbuser and dbpass from rc
    get tablenames from rc</tt></pre>
</div></div>
<div class="paragraph"><p>After initialisation, the fRun() function gets executed, which is the start of the functional code that will execute everything that needs to be executed.
In the listing below, we can see what the main code does in general.
Note:
The first <tt>exit when needed</tt> is a safety for when the option parsing main function does not exit properly when fRun() should not be called.</p></div>
<div class="listingblock">
<div class="title"><tt>fRun(self):</tt></div>
<div class="content">
<pre><tt>exit when needed
fConvert()
exit</tt></pre>
</div></div>
<div class="paragraph"><p>The conversion of the file gets called. It will open the database and the source file, read the source file and parse it. All the parsed values will be put in the correct table and column in the database.</p></div>
<div class="paragraph"><p>The special data is extra functionality I give to clipf, by (ab)using the comment field for certain products. This data will therefore have to be processed in a seperate function.</p></div>
<div class="listingblock">
<div class="title"><tt>fConvert(self):</tt></div>
<div class="content">
<pre><tt>connect to db
open cursor
open textfile
for each line
{
    for each field
    {
        look for values in db
        if they don't exist
        {
            add financial data
            add special data
        }
        else
        {
            check if date is &gt;= current date
            yes?
                add financial data
                add special data
        }
    }
}
close cur
close db
close file</tt></pre>
</div></div>
<div class="listingblock">
<div class="title"><tt>fConvertFinance(self, fields_db):</tt></div>
<div class="content">
<pre><tt>insert parsed values in tblfinance
show progress info</tt></pre>
</div></div>
<div class="listingblock">
<div class="title"><tt>fConvertSpecials(self, fields_db):</tt></div>
<div class="content">
<pre><tt>if we need to parse for stocks
{
    parse the comment field,
    to retrieve stock information
    convert stocks (=add to db)
}
otherwise, if we need to parse for bets
{
    parse te comment field,
    to retrieve betting information
    convert bets
}</tt></pre>
</div></div>
<div class="paragraph"><p>For stocks, we will need to do two things:
- Put all relevant information in a seperate table (tblstocks)
- Update the information about the the stocks we own at the current time.</p></div>
<div class="paragraph"><p>We will put the information in tblstocks first, using the fConvertStocks() function.</p></div>
<div class="listingblock">
<div class="title"><tt>fConvertStocks(self, fields_comment_db):</tt></div>
<div class="content">
<pre><tt>date_create en date_modify = current date + time
determine last added record
for this record, we add stock information in tblstocks</tt></pre>
</div></div>
<div class="paragraph"><p>Next, we will update the current stock information, using the fConvertStocksCurrent() function.</p></div>
<div class="listingblock">
<div class="title"><tt>fConvertStocksCurrent(self, fields_comment_db):</tt></div>
<div class="content">
<pre><tt>date_create en date_modify = current date + time
determine last added record
search for this records id in tblcurstocks
if it exists
{
    update the values it holds with the new data from our last added record:
    in-/decrease qty, change amount + buyval, ...
    if sum(qty) becomes zero
    {
        delete this entry from tblcurstocks
    }
}
else
{
    insert the new stock values in tblcurstocks
    Note: only insert date_create, don't update it!  Use only date_modify for updates.
}</tt></pre>
</div></div>
<div class="tableblock">
<table rules="all"
frame="hsides"
cellspacing="0" cellpadding="4">
<caption class="title">Table 1. Err&#8230; a table?</caption>
<col />
<col />
<col />
<col />
<col />
<col />
<col />
<col />
<thead>
<tr>
<th align="left" valign="top"> </th>
<th align="center" valign="top">Attributes </th>
<th align="center" valign="top">Callouts </th>
<th align="center" valign="top">Macros </th>
<th align="center" valign="top"> Quotes </th>
<th align="center" valign="top">Replacements</th>
<th align="center" valign="top">Special chars </th>
<th align="center" valign="top">Special words</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table"><em>OpenBlock</em></p></td>
<td align="center" valign="top"><p class="table">Yes</p></td>
<td align="center" valign="top"><p class="table">No</p></td>
<td align="center" valign="top"><p class="table">Yes</p></td>
<td align="center" valign="top"><p class="table">Yes</p></td>
<td align="center" valign="top"><p class="table">Yes</p></td>
<td align="center" valign="top"><p class="table">Yes</p></td>
<td align="center" valign="top"><p class="table">Yes</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2010-04-07 16:19:40 RDT
</div>
</div>
</body>
</html>
